/**
 iTextUploader
 (C) 2008 MyselftDev (myselftdev@gmail.com)
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; version 2
 of the License.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

/* Revision: $Id: ExportedView.m 65 2009-02-15 14:42:06Z myselftdev $ */

#import "ExportedView.h"

@implementation ExportedView

- (id)initWithFrame:(CGRect)frame dataObject:(PreferencesData*)theDataObject
{
	if ((self = [super initWithFrame:frame]))
	{
		data = [theDataObject retain];
		
		self.backgroundColor = [UIColor colorWithWhite:1.0 alpha:1.0];
		
		restoreButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
		[restoreButton retain];
		restoreButton.contentMode = UIViewContentModeRedraw;
		restoreButton.frame = CGRectMake(60.0, 40.0, 200.0, 40.0);
		restoreButton.font = [UIFont boldSystemFontOfSize:22.0];
		restoreButton.enabled = NO;
		[restoreButton setTitle:@"Restore backup" forState:UIControlStateNormal];
		[restoreButton setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled];
		[restoreButton addTarget:self action:@selector(restoreButtonClicked) forControlEvents:UIControlEventTouchUpInside];
		[self addSubview:restoreButton];
		
		webFrame = [ [UIWebView alloc] initWithFrame:CGRectMake(frame.origin.x, 120.0, frame.size.width, (frame.size.height - 120.0))];
		webFrame.userInteractionEnabled = NO;
		webFrame.delegate = nil;
		[self addSubview:webFrame];
		
		workingView = [ [AlertBox alloc] initAlertBox];
		
		[self checkExportedBox];
	}
	return self;
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
	if(buttonIndex != alertView.firstOtherButtonIndex)
	{
		return;
	}
	
	[self downloadFile];
}

- (void)restoreButtonClicked
{
	sqlite3 *db;
	int errcode;
	NSInteger lastMessage = 0;
	
	@try
	{
#if (TARGET_IPHONE_SIMULATOR)
		errcode = sqlite3_open([[[NSBundle mainBundle] pathForResource:@"sms" ofType:@"db"] UTF8String], &db);
#else
		errcode = sqlite3_open([[@UPLOAD_FILE stringByExpandingTildeInPath] UTF8String], &db);
#endif
		if(errcode)
		{
			NSException *e = [NSException exceptionWithName:@"SQLiteError" reason:@"Cannot open SMS database" userInfo:nil];
			@throw e;
		}
		
		sqlite3_stmt *query = nil;
		const char *sql = "SELECT MAX(date) FROM message";
		if(sqlite3_prepare_v2(db, sql, -1, &query, NULL) != SQLITE_OK)
		{
			NSLog(@"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(db));
			NSException *e = [NSException exceptionWithName:@"SQLiteError" reason:@"Cannot prepare query" userInfo:nil];
			@throw e;
		}
		
		if(sqlite3_step(query) == SQLITE_ROW)
		{
			lastMessage = (NSInteger) sqlite3_column_int(query, 0);
			NSLog(@"Last message date: %d", lastMessage);
		}
		else
		{
			NSException *e = [NSException exceptionWithName:@"SQLiteError" reason:@"No data returned from database" userInfo:nil];
			@throw e;
		}
		
		sqlite3_finalize(query);
		sqlite3_close(db);
		
		NSInteger lastUpload = [ [data getData:@"lastupload"] integerValue];
		if(lastMessage > lastUpload)
		{
			UIAlertView *alertMessage = [ [UIAlertView alloc] initWithTitle:@"Warning" message:@"It appears that your current database contains some messages not already imported in YouArchive.It. Are you sure you want to restore the exported file before importing the messages in YouArchive.It?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Continue", nil];
			[alertMessage show];
			[alertMessage autorelease];
		}
		else
		{
			[self downloadFile];
		}
	}
	@catch (NSException *e)
	{
		UIAlertView *alertMessage = [ [UIAlertView alloc] initWithTitle:@"SQLite Error" message:[e reason] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
		[alertMessage show];
		[alertMessage autorelease];
		
		sqlite3_close(db);
	}
}

- (void)downloadFile
{
	NSString *URLString = [NSString stringWithFormat:@"%@%@", @BASEURL, [@"remoteclient.php?appversion=" stringByAppendingString:@APPVERSION]];
	NSURL *theURL = [NSURL URLWithString:URLString];
	NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
	[theRequest setHTTPMethod: @"POST"];
	NSString *requestString = [NSString stringWithFormat:@"mode=getstoredfile&username=%@&password=%@", 
							   encodeURL((CFStringRef) [data getData:@"username"]),
							   encodeURL((CFStringRef) [data getData:@"password"])];
	[theRequest setHTTPBody:[requestString dataUsingEncoding:NSUTF8StringEncoding]];
	
	workingView.text = @"Downloading";
	workingView.hidden = NO;
	
	[receivedData release];
	
	downloadConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
	
	if(downloadConnection)
	{
		receivedData = [[NSMutableData alloc] init];
	}
	else
	{
		workingView.hidden = YES;
		[self connectionErrorAlertWithMessage:nil];
		[downloadConnection release];
	}
}

- (void)storeFile
{	
	@try
	{
		if([receivedData length] == 0)
		{
			NSException *e = [NSException exceptionWithName:@"Error" reason:@"Empty response" userInfo:nil];
			@throw e;
		}
		
		short i;
		 
		unsigned char *fileMD5cString = MD5([receivedData bytes], [receivedData length], NULL);
		NSMutableString *fileMD5 = nil;
		if(fileMD5cString)
		{	
			fileMD5 = [NSMutableString stringWithCapacity:32];
			for (i = 0; i < MD5_DIGEST_LENGTH; i++)
			{
				[fileMD5 appendFormat: @"%02x", (int)(fileMD5cString[i])];
			}
		}
		else
		{
			NSException *e = [NSException exceptionWithName:@"Error" reason:@"Error while calculatinc checksum" userInfo:nil];
			@throw e;
		}
		
		if(!fileMD5)
		{
			NSException *e = [NSException exceptionWithName:@"Error" reason:@"Error while calculatinc checksum" userInfo:nil];
			@throw e;
		}
		NSLog(@"Downloaded file checksum: %@ - Original checksum: %@", fileMD5, downloadChecksum);
		
		if(![downloadChecksum isEqualToString:fileMD5])
		{
			NSException *e = [NSException exceptionWithName:@"Error" reason:@"Checksum error. File corrupted?" userInfo:nil];
			@throw e;
		}
		
		NSFileManager *fileManager = [NSFileManager defaultManager];
		
		if([fileManager fileExistsAtPath:[@BACKUP_FILE stringByExpandingTildeInPath]])
		{
			if(![fileManager removeItemAtPath:[@BACKUP_FILE stringByExpandingTildeInPath] error:NULL])
			{
				NSException *e = [NSException exceptionWithName:@"Error" reason:@"Error while deleting old backup file" userInfo:nil];
				@throw e;
			}
		}
		
		if(![fileManager copyItemAtPath:[@UPLOAD_FILE stringByExpandingTildeInPath] toPath:[@BACKUP_FILE stringByExpandingTildeInPath] error:NULL])
		{
			NSException *e = [NSException exceptionWithName:@"Error" reason:@"Error while creating a backup copy of the file" userInfo:nil];
			@throw e;
		}
		
		if(![receivedData writeToFile:[@UPLOAD_FILE stringByExpandingTildeInPath] atomically:YES])
		{
			NSException *e = [NSException exceptionWithName:@"Error" reason:@"Error while storing new file" userInfo:nil];
			@throw e;
		}
		
		[receivedData setLength:0];
		workingView.hidden = YES;
		
		UIAlertView *alertMessage = [ [UIAlertView alloc] initWithTitle:@"Completed" message:@"Messages have been successfully restored.\nPLEASE REBOOT YOUR PHONE NOW!\n(Do NOT simply respring)" delegate:nil cancelButtonTitle:@"OK. I will reboot the phone." otherButtonTitles:nil];
		[alertMessage show];
		[alertMessage autorelease];
	}
	@catch (NSException * e)
	{
		workingView.hidden = YES;
		
		UIAlertView *alertMessage = [ [UIAlertView alloc] initWithTitle:@"Error" message:[e reason] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
		[alertMessage show];
		[alertMessage autorelease];
	}
}

- (void)connectionErrorAlertWithMessage:(NSString*)message
{
	NSString *showError = (message == nil) ? @"Couldn't complete connection" : message;
	workingView.hidden = YES;
	UIAlertView *alertMessage = [ [UIAlertView alloc] initWithTitle:@"Connection Error" message:showError delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
	[alertMessage show];
	[alertMessage autorelease];
}

- (void)checkExportedBox
{
	NSString *URLString = [NSString stringWithFormat:@"%@%@", @BASEURL, [@"remoteclient.php?appversion=" stringByAppendingString:@APPVERSION]];
	NSURL *theURL = [NSURL URLWithString:URLString];
	NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
	[theRequest setHTTPMethod: @"POST"];
	NSString *requestString = [NSString stringWithFormat:@"mode=exportboxstatus&username=%@&password=%@", 
							   encodeURL((CFStringRef) [data getData:@"username"]),
							   encodeURL((CFStringRef) [data getData:@"password"])];
	[theRequest setHTTPBody:[requestString dataUsingEncoding:NSUTF8StringEncoding]];
	
	workingView.text = @"Loading...";
	workingView.hidden = NO;
	
	[receivedData release];
	
	listConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
	
	if(listConnection)
	{
		receivedData = [[NSMutableData alloc] init];
	}
	else
	{
		workingView.hidden = YES;
		[self connectionErrorAlertWithMessage:nil];
		[listConnection release];
	}
}

- (void)listCompletedWithError:(BOOL)isError isEmpty:(BOOL)isEmpty checksum:(NSString *)checksum
{	
	if(isError)
	{
		[self connectionErrorAlertWithMessage:@"Invalid response"];
		return;
	}
	
	downloadChecksum = [checksum retain];
	
	NSURL *aURL;
	if(isEmpty)
	{
		aURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"ExportedViewNoFilesText" ofType:@"html"]];
		restoreButton.enabled = NO;
	}
	else
	{
		aURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"ExportedViewWithFilesText" ofType:@"html"]];
		restoreButton.enabled = YES;
	}
	
	NSURLRequest *aRequest=[NSURLRequest requestWithURL:aURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0];
	[webFrame loadRequest:aRequest];
}

- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
{
	[receivedData setLength:0];
}

- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)someData
{
	[receivedData appendData:someData];
}

- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
	[connection release];
	[receivedData release];
	workingView.hidden = YES;
	[self connectionErrorAlertWithMessage:[error localizedDescription]];
}

- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
	if(connection == listConnection)
	{
		workingView.hidden = YES;
		
		NSDictionary *result;
		@try
		{
			NSString *resultString = [[[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding] autorelease];
			
			result = [resultString propertyList];
			
			[self listCompletedWithError:[[result objectForKey:@"error"] boolValue] isEmpty:[[result objectForKey:@"empty"] boolValue] checksum:[result objectForKey:@"checksum"]];
		}
		@catch(NSException *e)
		{
			[self listCompletedWithError:YES isEmpty:YES checksum:@""];
		}
	}
	else if(connection == downloadConnection)
	{
		[self storeFile];
	}
	
	[connection release];
}

- (void)dealloc {
	[restoreButton release];
	[webFrame release];
	[workingView release];
	
	[listConnection release];
	[downloadConnection release];
	[receivedData release];
	[downloadChecksum release];
	
	[data release];
	
	[super dealloc];
}


@end
